# encoding=utf-8
import logging
import os.path
import time
from datetime import datetime

from SerialRecv import SerialRecv
from SerialSend import SerialSend


# logging.basicConfig(level = logging.INFO,format = '%(asctime)s - %(name)s - %(levelname)s - %(message)s')


class SerialDevice(SerialSend, SerialRecv):
    def __init__(self,
                 device: str,
                 rate: int = 115200,
                 package_size: int = 64,
                 tmp_dir: str = "tmp-data-device"):
        super().__init__(device, rate, package_size)
        # 环境信息
        self.tmp_dir = tmp_dir
        os.makedirs(self.tmp_dir, exist_ok=True)

        # 指令记录码
        self.host_command = 0xff
        self.host_sub_command = 0xff

        # 接收到的文件
        self.device_now_file = ""
        # 外部设置的将要发送的文件
        self.send_now_file = ""

        # 执行状态
        self.device_status = 0xff

        # 从: 模块启动 -> 清空所有串口缓存
        self._make_sure_flush()

    def event_loop(self):
        # 从：进入指令等待模式
        while True:
            # 读取总线缓冲
            data_len = self.serial.in_waiting

            if data_len == 0:
                # sleep 10ms
                time.sleep(0.01)

            if data_len != 0 and data_len != 2 :
                # 有杂数据
                logging.warning("Error Data maybe occur")
                self._make_sure_flush()

            if data_len == 2:
                # 从: 接收指令
                command = bytearray(self._read_raw_data(2))
                self.host_command = command[0]
                self.host_sub_command = command[1]

                logging.info("Recv Command: {}, Sub Command: {}".format(self.host_command, self.host_sub_command))

                # 指令判断
                if self.host_command == self.OUT:
                    # 从: 返回应答码
                    self._send_raw_data(self.get_command_byte(self.ACK))

                    # 从: 进入原始数据等待模式, recv_raw_file
                    self.device_now_file = self._gen_file_name(".jpg")
                    status = self.recv_raw_file(self.device_now_file)

                    if not status:
                        self.device_status = self.QUERY_ERROR
                    else:
                        self.device_status = self.QUERY_PENDING

                        # TODO: 触发处理事件，或者开启处理线程
                        self.device_status = self.QUERY_DONE
                        if self.host_sub_command == 1:
                            self.send_now_file = "sample-data/sample2.jpg"
                        else:
                            self.send_now_file = "sample-data/sample_json.txt"

                if self.host_command == self.QUERY:
                    self._send_raw_data(self.get_command_byte(self.device_status))
                    # 如果已经产生错误，在一次查询后清空状态
                    if self.device_status == self.QUERY_ERROR:
                        self._clean_status()

                if self.host_command == self.IN:
                    time.sleep(0.01)
                    self.send_raw_file(self.send_now_file)
                    # 完成后清空状态
                    self._clean_status()

    def _clean_status(self):
        self.host_command = 0xff
        self.host_sub_command = 0xff
        self.device_status = 0xff
        self.device_now_file = ""
        self.send_now_file = ""
        self._make_sure_flush()

    def _gen_file_name(self, suffix: str = ".jpg"):
        time_name = datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
        return os.path.join(self.tmp_dir, time_name + suffix)

if __name__ == '__main__':
    # 1. 从: 模块启动 -> 清空所有串口缓存
    # 2. 从：进入指令等待模式
    serial_device = SerialDevice("/dev/ttyACM1", 6000000, 256)
    serial_device.event_loop()
